package com.plum.admin.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.plum.admin.common.constant.Constant;
import com.plum.admin.common.datascope.DataScope;
import com.plum.admin.common.exception.BaseException;
import com.plum.admin.common.util.PasswordUtil;
import com.plum.admin.common.util.RedisCache;
import com.plum.admin.modules.sys.dto.UserDTO;
import com.plum.admin.modules.sys.entity.SysRole;
import com.plum.admin.modules.sys.entity.SysUser;
import com.plum.admin.modules.sys.entity.SysUserRole;
import com.plum.admin.modules.sys.mapper.SysUserMapper;
import com.plum.admin.modules.sys.service.ISysDeptService;
import com.plum.admin.modules.sys.service.ISysMenuService;
import com.plum.admin.modules.sys.service.ISysRoleService;
import com.plum.admin.modules.sys.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 子丶沫
 * @since 2021-08-13
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private RedisCache redisCache;
    @Override
    public SysUser findByUsername(String username) {
        SysUser user = baseMapper.findByUsername(username);
        return buildUser(user);
    }
    @Override
    public SysUser findByUserMobile(String mobile) {
        SysUser user = baseMapper.findUserByMobile(mobile);
        return buildUser(user);
    }
    @Override
    public SysUser findByEmail(String email){
        return baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail,email));
    }
    private SysUser buildUser(SysUser user){
        if(ObjectUtil.isNotNull(user)){
            Set<String> permission = menuService.findPermissionByUserId(user.getId())
                    .stream().filter(StrUtil::isNotBlank)
                    .map(data -> data.split(","))
                    .flatMap(Arrays::stream)
                    .collect(Collectors.toSet());
            List<SysRole> roleList = roleService.findRoleByUserId(user.getId());
            Set<String> roles = roleList.stream().
                    map(role -> "ROLE_" + role.getId())
                    .collect(Collectors.toSet());
            permission.addAll(roles);
            user.setPermissionList(permission);
            user.setRoleList(roleList);
            return user;
        }
        return null;
    }
    @Override
    public IPage<SysUser> queryUserList(IPage<SysUser> page, UserDTO userDTO) {
        if(ObjectUtil.isNotNull(userDTO)&&ObjectUtil.isNotNull(userDTO.getDeptId())){
            List<String> deptIds = deptService.queryDeptIds(userDTO.getDeptId());
            userDTO.setDeptList(deptIds);
        }
        return page.setRecords(baseMapper.queryUserPage(page,userDTO,new DataScope()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(List<String> idList) {
        for (String id : idList) {
            if(Constant.ADMIN_USER_ID.equals(id)){
                continue;
            }
            int i=baseMapper.deleteById(id);
            if(i>0){
                baseMapper.deleteUserRole(id);
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertUser(UserDTO userDTO) {
        SysUser user=new SysUser();
        BeanUtil.copyProperties(userDTO,user);
        String password = PasswordUtil.encodePassword(user.getPassword());
        user.setPassword(password);
        int insert = baseMapper.insert(user);
        if(insert>0&&CollUtil.isNotEmpty(userDTO.getRoleList())){
            List<String> roleList = userDTO.getRoleList();
            List<SysUserRole> userRoleList = roleList.stream().map(roleId -> {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(user.getId());
                sysUserRole.setRoleId(roleId);
                return sysUserRole;
            }).collect(Collectors.toList());
            baseMapper.insertUserRole(userRoleList);
        }
        return insert>0;
    }

    @Override
    public boolean updateUser(UserDTO userDTO) {
        SysUser user=new SysUser();
        BeanUtil.copyProperties(userDTO,user);
        int update = baseMapper.updateById(user);
        if(update>0&&CollUtil.isNotEmpty(userDTO.getRoleList())){
            baseMapper.deleteUserRole(user.getId());
            List<SysUserRole> userRoleList = userDTO.getRoleList().stream().map(roleId -> {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(user.getId());
                sysUserRole.setRoleId(roleId);
                return sysUserRole;
            }).collect(Collectors.toList());
            baseMapper.insertUserRole(userRoleList);
        }
        return update>0;
    }

    @Override
    public boolean checkUsername(String username) {
        return baseMapper.selectList(Wrappers.<SysUser>lambdaUpdate().eq(SysUser::getUsername,username)).size()>0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int register(UserDTO userDTO, String smsCode) {
        Object cacheObject = redisCache.getCacheObject(Constant.SMS_PRE + userDTO.getPhone());
        if(StrUtil.isBlank(smsCode)){
            throw new BaseException("验证码不能为空");
        }
        if(ObjectUtil.isNull(cacheObject)){
            throw new BaseException("验证码不存在");
        }
        String code = String.valueOf(cacheObject);
        if(!StrUtil.equals(code,smsCode)){
            throw new BaseException("验证码不正确");
        }
        SysUser user=new SysUser();
        BeanUtil.copyProperties(userDTO,user);
        user.setPassword(PasswordUtil.encodePassword("123456"));
        user.setDeptId("5");
        baseMapper.insert(user);
        SysUserRole userRole=new SysUserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId("8");
        return baseMapper.insertUserRole(Lists.newArrayList(userRole));
    }

    @Override
    public int updatePassword(SysUser user, String password, HttpServletRequest request) {
        user.setPassword(PasswordUtil.encodePassword(password));
        return baseMapper.updateById(user);
    }
}
